﻿Option Strict On
Option Explicit On
Option Infer On

Imports System
Imports GenDotNet.TemplateSupport.StandardAttributeExtensions
Imports GenDotNet.Task.Common
Imports GenDotNet.Model.Common
Imports System.Xml.Linq

''' <summary>
''' Provides common naming patterns which can be modified for anticipated names
''' and two mechanisms for extensibiity to your own naming.
''' </summary>
''' <remarks>
''' Notes on extensibility:<para/>
''' 1) You can create extension methods of the naming factory class in a module of 
''' your project and add the new naming routines there. This is the simplest approach, 
''' but extension methods provide no further extensibility points. 
''' <para/>
''' 2) You can provide additional naming by deriving from this class and overriding 
''' the GetCustomName method. It takes an integer, which it excpects to be a constant
''' within your code, probably within your derived class. Set the NamingFactory property
''' of each template before using the naming factory. You can do this once for all of 
''' the templates in a given project by creating an intervening base class for all 
''' templates in that project.
''' <para/>
''' 3) You can derive from this class and add new methods corresponding to names you'd 
''' like to add. The problem becomes accessing these methods since the NamingFactory 
''' property in TemplateBase is typed to this class. You could of course cast in your
''' code, but this is a bad idea as it spreads details of your implementation throughout
''' your code. A better approach is to shadow (new in C#) the NamingFactory property to return  
''' your own type. This means the TemplateBase NamingFactory property will not be visible to 
''' derived classes, only your new NamingFactory property will be visible. Shadowing 
''' becomes confusing when you can cast objects to the base class because if you cast
''' to anything closer to TemplateBase you will get the TemplateBase version. Becuase
''' this could cause confusion, the NamingFactory property in TemplateBase is Protected.
''' </remarks>
Public Class NamingFactory
   Private mClassNamePattern As String
   Private mGeneratedNamePattern As String
   Private mDesginerNamePattern As String
   Private mCollectionNamePattern As String
   Private mReadOnlyItemNamePattern As String
   Private mReadOnlyListNamePattern As String
   Private mDalNamePattern As String

#Region "Properties"
   Public Property ClassNamePattern() As String
      Get
         If mClassNamePattern Is Nothing Then
            Return "{0}"
         End If
         Return mClassNamePattern
      End Get
      Set(ByVal value As String)
         mClassNamePattern = value
      End Set
   End Property

   Public Property GeneratedNamePattern() As String
      Get
         If mGeneratedNamePattern Is Nothing Then
            Return "gen{0}"
         End If
         Return mDesginerNamePattern
      End Get
      Set(ByVal value As String)
         mGeneratedNamePattern = value
      End Set
   End Property

   Public Property DesginerNamePattern() As String
      Get
         If mDesginerNamePattern Is Nothing Then
            Return "{0}.Designer"
         End If
         Return mDesginerNamePattern
      End Get
      Set(ByVal value As String)
         mDesginerNamePattern = value
      End Set
   End Property

   Public Property CollectionNamePattern() As String
      Get
         If mCollectionNamePattern Is Nothing Then
            Return "{0}Collection"
         End If
         Return mCollectionNamePattern
      End Get
      Set(ByVal value As String)
         mCollectionNamePattern = value
      End Set
   End Property

   Public Property ReadOnlyItemNamePattern() As String
      Get
         If mReadOnlyItemNamePattern Is Nothing Then
            Return "{0}Info"
         End If
         Return mReadOnlyItemNamePattern
      End Get
      Set(ByVal value As String)
         mReadOnlyItemNamePattern = value
      End Set
   End Property

   Public Property ReadOnlyListNamePattern() As String
      Get
         If mReadOnlyListNamePattern Is Nothing Then
            Return "{0}List"
         End If
         Return mReadOnlyListNamePattern
      End Get
      Set(ByVal value As String)
         mReadOnlyListNamePattern = value
      End Set
   End Property

   Public Property DalNamePattern() As String
      Get
         If mDalNamePattern Is Nothing Then
            Return "{0}Dal"
         End If
         Return mDalNamePattern
      End Get
      Set(ByVal value As String)
         mDalNamePattern = value
      End Set
   End Property


#End Region

#Region "Methods"
   Public Overridable Function GetCustomName(ByVal type As Int32, ByVal name As String) As String
      Throw New NotImplementedException("This method is not meaningful unless overridden in a derived class")
   End Function

   Public Overridable Function GetClassName(ByVal name As String) As String
      Return String.Format(ClassNamePattern, name)
   End Function

   Public Overridable Function GetGeneratedName(ByVal name As String) As String
      Return String.Format(GeneratedNamePattern, name)
   End Function

   Public Overridable Function GetDesignerName(ByVal name As String) As String
      Return String.Format(DesginerNamePattern, name)
   End Function

   Public Overridable Function GetCollectionName(ByVal name As String) As String
      Return String.Format(CollectionNamePattern, name)
   End Function

   Public Overridable Function GetReadOnlyItemName(ByVal name As String) As String
      Return String.Format(ReadOnlyItemNamePattern, name)
   End Function

   Public Overridable Function GetReadOnlyListName(ByVal name As String) As String
      Return String.Format(ReadOnlyListNamePattern, name)
   End Function

   Public Overridable Function GetDalName(ByVal name As String) As String
      Return String.Format(DalNamePattern, name)
   End Function

#End Region
End Class
